#include <iostream>
#include <winsock2.h>
#include <windows.h>
#pragma comment(lib, "ws2_32.lib")

// DHCP报文结构（简化）
struct DhcpPacket {
    unsigned char op;         // 1=请求，2=响应
    unsigned char htype;      // 硬件类型（1=以太网）
    unsigned char hlen;       // 硬件地址长度（6）
    unsigned char hops;       // 跳数
    unsigned int xid;         // 事务ID
    unsigned short secs;      // 秒数
    unsigned short flags;     // 标志（广播=0x8000）
    unsigned int ciaddr;      // 客户端IP
    unsigned int yiaddr;      // 分配的IP
    unsigned int siaddr;      // 服务器IP
    unsigned int giaddr;      // 网关IP
    unsigned char chaddr[16]; // 客户端MAC（前6字节）
    char sname[64];           // 服务器名
    char file[128];           // 启动文件名
    unsigned char options[312];// 选项
};

void dhcpServer() {
    WSADATA wsa;
    WSAStartup(MAKEWORD(2, 2), &wsa);

    SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    int opt = 1;
    setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&opt, sizeof(opt));

    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    serverAddr.sin_port = htons(67); // DHCP服务器端口
    bind(sock, (sockaddr*)&serverAddr, sizeof(serverAddr));

    // 配置固定分配的IP信息
    unsigned int assignedIp = inet_addr("192.168.1.2");
    unsigned int subnetMask = inet_addr("255.255.255.0");
    unsigned int gateway = inet_addr("192.168.1.1");
    unsigned int dns = inet_addr("192.168.1.1");

    DhcpPacket packet;
    sockaddr_in clientAddr;
    int clientLen = sizeof(clientAddr);

    while (true) {
        recvfrom(sock, (char*)&packet, sizeof(packet), 0, 
            (sockaddr*)&clientAddr, &clientLen);

        if (packet.op == 1) { // 客户端请求
            // 构建OFFER响应
            packet.op = 2;
            packet.yiaddr = assignedIp; // 分配固定IP
            packet.siaddr = inet_addr("192.168.1.254"); // 服务器IP
            packet.giaddr = gateway;

            // 填充选项（Magic Cookie + OFFER + 网络参数）
            unsigned char options[] = {
                0x63, 0x82, 0x53, 0x63, // Magic Cookie
                0x35, 0x01, 0x02,       // DHCP OFFER
                0x01, 0x04, (subnetMask >> 24) & 0xFF, (subnetMask >> 16) & 0xFF, 
                (subnetMask >> 8) & 0xFF, subnetMask & 0xFF, // 子网掩码
                0x03, 0x04, (gateway >> 24) & 0xFF, (gateway >> 16) & 0xFF, 
                (gateway >> 8) & 0xFF, gateway & 0xFF, // 网关
                0x06, 0x04, (dns >> 24) & 0xFF, (dns >> 16) & 0xFF, 
                (dns >> 8) & 0xFF, dns & 0xFF, // DNS
                0xFF                    // 结束
            };
            memcpy(packet.options, options, sizeof(options));

            // 广播发送响应到客户端端口68
            clientAddr.sin_port = htons(68);
            clientAddr.sin_addr.s_addr = INADDR_BROADCAST;
            sendto(sock, (char*)&packet, sizeof(packet), 0, 
                (sockaddr*)&clientAddr, clientLen);
            std::cout << "已发送IP分配: 192.168.1.2" << std::endl;
        }
    }
    closesocket(sock);
    WSACleanup();
}

int main() {
    dhcpServer();
    return 0;
}